/*
 * Copyright 2014 Jonathan Haas
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

package app.grinreader.model;

import nl.siegmann.epublib.domain.Resource;

import java.util.ArrayList;
import java.util.List;
import java.util.Stack;
import java.util.regex.Pattern;

/**
 *
 */
public class ParagraphBuilder {

	private final Stack<StyleElement> markupStack = new Stack<>();
	private List<TextBlock> resultList;
	private List<Element> elements = new ArrayList<>();
	private int resourceId;
	private static final Pattern PATTERN = Pattern.compile("[ \\n\\t]+");
	private boolean shouldSkipSpace = true;

	public ParagraphBuilder(List<TextBlock> resultList, int resourceId) {
		this.resultList = resultList;
		this.resourceId = resourceId;
	}

	public void finishParagraph() {
		if(elements.size() == 0) return;
		resultList.add(new TextBlock(elements.toArray(new Element[elements.size()]), resourceId, resultList.size()));
		elements.clear();
		shouldSkipSpace = true;
	}

	public void appendText(String text) {
		// Mimic HTML space behaviour
		if(text.length() == 0) return;
		text = PATTERN.matcher(text).replaceAll(" ");
		if(text.charAt(0) == ' ' && shouldSkipSpace){
			text = text.substring(1);
		}
		if(text.length() == 0) return;
		shouldSkipSpace = text.charAt(text.length()-1) == ' ';
		elements.add(new TextElement(text));
	}

	public void addMarkupStack(StyleElement textMarkup) {
		markupStack.addElement(textMarkup);
		elements.add(textMarkup);
	}

	public void popMarkupStack() {
		markupStack.pop();
		elements.add(ClearStyleElement.getInstance());
		for (StyleElement styleElement : markupStack) {
			elements.add(styleElement);
		}
	}

	public void appendLineBreak() {
		elements.add(LineBreakElement.getInstance());
	}

	public void appendImage(Resource src) {
		elements.add(new ImageElement(src));
	}
}
